package jp.co.kayo.gae.takidashibot.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;

import org.slim3.datastore.Datastore;

import jp.co.kayo.gae.takidashibot.meta.TakidasiMeta;
import jp.co.kayo.gae.takidashibot.model.Takidasi;
import jp.co.kayo.gae.takidashibot.utils.Coords;
import jp.co.kayo.gae.takidashibot.utils.MyComparator;
import jp.co.kayo.gae.takidashibot.utils.TakidasiPair;
import jp.co.kayo.gae.takidashibot.utils.TwitterClient;
import jp.co.kayo.gae.takidashibot.utils.Utils;

import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.StatusUpdate;
import twitter4j.TwitterException;


public class TweetCheck extends TwitterSerivce {
    private static final int T_DIST = 30000;
    
    private boolean needAutoSend(Status status, String screen_name){
        String text = status.getText();
        if(text.indexOf("RT") != -1
        || text.indexOf("QT") != -1){
            if(text.contains(screen_name)){
                return false;
            }
        }
        else if(text.contains("http")){
            return false;
        }
        return true;
    }
    
    public boolean autoSay(TwitterClient client, TwitterClient talker) throws TwitterException{
        //bot0
        ResponseList<Status> statuses = client.getMentions();
        if (statuses != null) {
            Long lastdate = (Long)client.getLastProc();
            for(int i=statuses.size()-1; i>=0; i--){
                Status status = statuses.get(i);
                //System.out.println(status.getCreatedAt()+"：" + status.getText());
                if(lastdate == null || status.getCreatedAt().getTime() > lastdate){
                    client.setLastProc(status.getCreatedAt().getTime());
                    //返事、あるいは処理をするのは自分宛て、あるいはただのつぶやきの場合のみ処理を行う
                    String text = status.getText();
                    //自分のメッセージはキャンセルね
                    if(client.getScreenName().equals(status.getUser().getScreenName())){
                        continue;
                    }
                    //公式RTもキャンセルね
                    if(status.isRetweet()){
                        continue;
                    }
                    if(needAutoSend(status, client.getScreenName())){
                        log.log(Level.INFO, status.getCreatedAt()+"：" + status.getText());
                        //自分宛て
                        if(client.getScreenName().equals(status.getInReplyToScreenName())){
                            if(henji(client, talker, status)){
                                return true;
                            }
                        }
                    }
                }
            }
        }
        
        return false;
    }
    
    private boolean henji(TwitterClient client, TwitterClient talker, Status status){
        String text = status.getText();
        String scname = status.getUser().getScreenName();
        //該当地域外は反応しないように
        if(
            text.contains("宮城")
         || text.contains("福島")
         || text.contains("茨城")
         || text.contains("栃木")
         || text.contains("青森")
         || text.contains("岩手")
         || text.contains("山形") ){
            
            //メンションの文字列を消去する
            String msg = text.replace("@", "");
            msg = msg.replace(talker.getScreenName(), "");
            msg = msg.replace(client.getScreenName(), "");
            
            double[] ret = Utils.getGeoCode(msg);
            if(ret!=null){
                try {
                    TakidasiMeta tm = TakidasiMeta.get();
                    List<Takidasi> points = Datastore.query(tm).asList();
                    if (points != null && points.size() > 1) {
                        //対象となるデータを抽出
                        ArrayList<TakidasiPair> founds = new ArrayList<TakidasiPair>();
                        for(Takidasi t : points){
                           double lat1 = t.getLat();
                           double lng1 = t.getLng();
                           double lat2 = ret[0];
                           double lng2 = ret[1];
                           double m = Coords.calcDistHubeny(lat1, lng1, lat2, lng2);
                           if(m<T_DIST){
                               founds.add(new TakidasiPair(m, t));
                           }
                        }
                        
                        //返事用のデータ５件を抽出
                        if(founds.size()>0){
                            StringBuilder b = new StringBuilder();
                            b.append("@").append(scname).append(" ");
                            b.append(founds.size()+"件の炊き出し情報がみつかったよ！");
                            if(founds.size()>5){
                                b.append("数が多いので一番近いところから５件だけ教えるね。");
                                StringBuilder srcurl = new StringBuilder();
                                srcurl.append("http://takidasibot.appspot.com/takidasibot/list.html?lat=").append(ret[0]).append("&lng=").append(ret[1]).append("&m=30000");
                                String shorturl = Utils.urlShorter(srcurl.toString());
                                if(shorturl!=null && shorturl.length()>0){
                                    b.append(" それから、詳しくはこのURLから見れるよっ ").append(shorturl);
                                }
                            }
                            StatusUpdate state = new StatusUpdate(b.toString());
                            state.setInReplyToStatusId(status.getId());
                            talker.say(state);
                            
                            Collections.sort(founds, new MyComparator(T_DIST));
                            int count = 0;
                            for(TakidasiPair t : founds){
                                if((count++) >= 5){
                                    break;
                                }
                                double km = t.dist/1000;
                                double lat1 = t.takidasi.getLat();
                                double lng1 = t.takidasi.getLng();
                                String str = new Henjitter().kokodayo(scname, t.takidasi, lat1, lng1, km);
                                //System.out.println("Text Length="+str.length());
                                try {
                                    //つぶやく　
                                    state = new StatusUpdate(str);
                                    state.setInReplyToStatusId(status.getId());
                                    talker.updateState(state);
                                 } catch (TwitterException e) {
                                     log.log(Level.WARNING, "updateState", e);
                                 }
                            }
                        }
                        else{
                          //データがない
                            try {
                                StringBuilder b = new StringBuilder();
                                b.append("@").append(scname).append(" ");
                                b.append("問い合わせの住所から30km圏内に炊き出し地点はないようです。");
                                 StatusUpdate state = new StatusUpdate(b.toString());
                                 state.setInReplyToStatusId(status.getId());
                                 talker.updateState(state);
                             } catch (TwitterException e) {
                                 log.log(Level.WARNING, "updateState", e);
                             }
                        }
                    }
                    else {
                        //データがない
                        try {
                            StringBuilder b = new StringBuilder();
                            b.append("@").append(scname).append(" ");
                            b.append("実はまだ炊き出し情報がないの、またあとでアクセスしてみて。");
                            StatusUpdate state = new StatusUpdate(b.toString());
                            state.setInReplyToStatusId(status.getId());
                            talker.updateState(state);
                         } catch (TwitterException e) {
                             log.log(Level.WARNING, "updateState", e);
                         }
                    }
                }
                finally{
                    //if (tx.isActive()) tx.rollback();
                }
            }
            else{
                try {
                    StringBuilder b = new StringBuilder();
                    b.append("@").append(scname).append(" ");
                    b.append("住所を特定できなかったよ。ごめんね");
                    b.append(" [").append(msg).append("]");
                    StatusUpdate state = new StatusUpdate(b.toString());
                    state.setInReplyToStatusId(status.getId());
                    talker.updateState(state);
                 } catch (TwitterException e) {
                     log.log(Level.WARNING, "updateState", e);
                 }
            }
            return true;
        }
        else{
            if(text.indexOf("県")!=-1 
               || text.indexOf("区")!=-1
               || text.indexOf("市")!=-1
                || text.indexOf("町")!=-1){
                try {
                    StringBuilder b = new StringBuilder();
                    b.append("@").append(scname).append(" ");
                    b.append("次の県が含まれていない住所は検索できませんよっ！　[宮城、福島、茨城、栃木、青森、岩手、山形]");
                    StatusUpdate state = new StatusUpdate(b.toString());
                    state.setInReplyToStatusId(status.getId());
                    talker.updateState(state);
                    return true;
                 } catch (TwitterException e) {
                     log.log(Level.WARNING, "updateState", e);
                 }
            }
        }
        return false;
    }    
}
